package com.fingard.dsp.bank.directbank.allinpay02;

import com.alibaba.fastjson.JSONObject;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.RefundState;
import com.fingard.dsp.bank.directbank.allinpay02.util.SybUtil;
import com.fingard.dsp.bank.directbank.bankInterface.IRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.ReqQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.ReqRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.RetAtsQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.RetAtsRecRefund;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;

import java.util.Calendar;
import java.util.Date;
import java.util.TreeMap;

public class AllInPay02RecRefund extends AllInPay02Base implements IRecRefund {
    @Override
    public RetAtsRecRefund submitRecRefund(ReqRecRefund p_reqRef) throws Exception {
        if ("GW02".equals(p_reqRef.reqHeader.commandCode)) {
            return submitGWRecRefund(p_reqRef);
        } else {
            return submitOrdinaryRecRefund(p_reqRef);
        }
    }

    /**
     * 接口地址：https://aipboss.allinpay.com/know/devhelp/main.php?pid=13
     **/
    public RetAtsRecRefund submitGWRecRefund(ReqRecRefund p_reqRef) throws Exception {
        RetAtsRecRefund retAts = new RetAtsRecRefund();
        retAts.oriRdSeq = p_reqRef.oriRdSeq;
        retAts.refundNo = p_reqRef.refundNo;
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqRef.ownAct, "unifiedorder");
            if (actItem != null) {
                TreeMap<String, String> params = new TreeMap<String, String>();
                params.put("cusid", actItem.merchantId);/* 商户号 */
                params.put("appid", actItem.appId); /* 应用ID*/
                params.put("reqsn", p_reqRef.refundNo);/* 商户退款流水 */
                params.put("trxamt", StringHelper.amountMultiply100(p_reqRef.amount));/* 退款金额 */
                params.put("orderid", p_reqRef.oriRdSeq); /* 原始交易订单号 */
                params.put("trxid", "");/* 平台交易流水 */
                params.put("remark", p_reqRef.decription);/* 备注 */
                params.put("notifyurl", actItem.notifyURL); /* 服务器异步通知页面路径 */
                params.put("randomstr", get_nonce_str());/* 随机字符串 */
                String signMessage = sign(params, actItem.saltKey);
                params.put("sign", signMessage);/* 签名 */

                String url = bankFront.getUrl("gateWayRefund");
                String tmpRetStr = sendUnifiedToBank(params, url);

                if (StringHelper.hasAnyChar(tmpRetStr)) {
                    if (tmpRetStr.indexOf("{") >= 0) {
                        JSONObject respJson = JSONObject.parseObject(tmpRetStr);

                        String respCode = respJson.getString("retcode");
                        if ("SUCCESS".equals(respCode)) {
                            retAts.respCode = "0";
                            retAts.respInfo = respJson.getString("errmsg");
                            String trxStatus = respJson.getString("trxstatus");
                            if ("0000".equals((trxStatus)) || "2008".equals(trxStatus) || "2000".equals(trxStatus)) {
                                retAts.refundState = RefundState.REFUND_PAYING;
                            } else {
                                String payState = this.getBankConfig().getMapAdvanceValue("recRefundMapping", "key", "payState", trxStatus);
                                if ("3".equals(payState)) {
                                    retAts.refundState = RefundState.REFUND_FAIL;
                                } else {
                                    retAts.refundState = RefundState.REFUND_PAYING;
                                }
                            }

                            retAts.originalCode = trxStatus;
                            String originalInfo = respJson.getString("errmsg");
                            if (StringHelper.isNullOrEmpty(originalInfo)) {
                                originalInfo = "SUCCESS";
                            }
                            retAts.originalInfo = originalInfo;
                            retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", trxStatus);
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = respJson.getString("retmsg");
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpRetStr;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "通联响应数据为空";
                }
            } else {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号[" + p_reqRef.ownAct + "]商户配置信息!";
                retAts.refundState = RefundState.REFUND_FAIL;
                retAts.originalCode = "E9981";
                retAts.originalInfo = retAts.respInfo;
                retAts.unifiedCode = "E9981";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    /**
     * 4.3 交易撤销 https://aipboss.allinpay.com/know/devhelp/main.php?pid=15#mid=91
     * 4.4 交易退款 https://aipboss.allinpay.com/know/devhelp/main.php?pid=15#mid=92
     */
    public RetAtsRecRefund submitOrdinaryRecRefund(ReqRecRefund p_reqRef) throws Exception {
        RetAtsRecRefund retAts = new RetAtsRecRefund();
        retAts.oriRdSeq = p_reqRef.oriRdSeq;
        retAts.refundNo = p_reqRef.refundNo;
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqRef.ownAct, "unifiedorder");
            if (actItem != null) {
                String url = bankFront.getUrl("cancelPayment");
                TreeMap<String, String> params = new TreeMap<String, String>();
                params.put("cusid", actItem.merchantId);/* 商户号 */
                params.put("appid", actItem.appId); /* 应用ID*/
                params.put("version", "11");/* 版本号 */
                params.put("trxamt", StringHelper.amountMultiply100(p_reqRef.amount));/* 退款金额 */
                params.put("reqsn", p_reqRef.refundNo); /* 商户退款订单号 */
                params.put("oldreqsn", p_reqRef.oriRdSeq);/* 原交易订单号 */
                params.put("oldtrxid", "");/* 原交易流水 */

                String s = p_reqRef.oriTransDate;
                if ((DateHelper.compareDay(Format.DateTimeFormat.parse(s), new Date())) < 0) {
                    params.put("remark", p_reqRef.decription);/* 备注 */
                    params.put("benefitdetail", "");/* 优惠信息 */
                    url = bankFront.getUrl("submitRecRefund");
                }
                params.put("randomstr", get_nonce_str());/* 随机字符串 */
                params.put("sign", SybUtil.sign(params, actItem.saltKey)); /* 签名 */

                String tmpRetStr = sendUnifiedToBank(params, url);

                if (StringHelper.hasAnyChar(tmpRetStr)) {
                    if (tmpRetStr.indexOf("{") >= 0) {
                        JSONObject respJson = JSONObject.parseObject(tmpRetStr);

                        String respCode = respJson.getString("retcode");
                        if ("SUCCESS".equals(respCode)) {
                            retAts.respCode = "0";
                            retAts.respInfo = respJson.getString("errmsg");
                            String trxStatus = respJson.getString("trxstatus");

                            if ("0000".equals((trxStatus))) {
                                retAts.refundState = RefundState.REFUND_SUCCESS;
                            } else if ("2008".equals(trxStatus) || "2000".equals(trxStatus)) {
                                retAts.refundState = RefundState.REFUND_PAYING;
                            } else {
                                String payState = this.getBankConfig().getMapAdvanceValue("recRefundMapping", "key", "payState", trxStatus);
                                if ("3".equals(payState)) {
                                    retAts.refundState = RefundState.REFUND_FAIL;
                                } else {
                                    retAts.refundState = RefundState.REFUND_PAYING;
                                }
                            }

                            retAts.originalCode = trxStatus;
                            String originalInfo = respJson.getString("errmsg");
                            if (StringHelper.isNullOrEmpty(originalInfo)) {
                                originalInfo = "SUCCESS";
                            }
                            retAts.originalInfo = originalInfo;
                            retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", trxStatus);
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = respJson.getString("retmsg");
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpRetStr;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "通联响应数据为空";
                }
            } else {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号[" + p_reqRef.ownAct + "]商户配置信息!";
                retAts.refundState = RefundState.REFUND_FAIL;
                retAts.originalCode = "E9981";
                retAts.originalInfo = retAts.respInfo;
                retAts.unifiedCode = "E9981";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    @Override
    public RetAtsQryRecRefund queryRecRefund(ReqQryRecRefund p_reqQryRef) throws Exception {
        if ("GW02".equals(p_reqQryRef.reqHeader.commandCode)) {
            return queryGWRecRefund(p_reqQryRef);
        } else {
            return queryOrdinaryRecRefund(p_reqQryRef);
        }
    }

    public RetAtsQryRecRefund queryGWRecRefund(ReqQryRecRefund p_reqQryRef) throws Exception {
        RetAtsQryRecRefund retAts = new RetAtsQryRecRefund();
        retAts.oriRdSeq = p_reqQryRef.oriRdSeq;
        retAts.refundNo = p_reqQryRef.refundNo;
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQryRef.ownAct, "unifiedorder");
            if (actItem != null) {
                TreeMap<String, String> params = new TreeMap<String, String>();

                params.put("cusid", actItem.merchantId);/* 商户号 */
                params.put("appid", actItem.appId); /* 应用ID*/
                params.put("orderid", p_reqQryRef.refundNo);/* 商户订单号 */
                params.put("trxid", ""); /* 平台交易流水 */
                params.put("randomstr", get_nonce_str());/* 随机字符串 */
                String signMessage = sign(params, actItem.saltKey);
                params.put("sign", signMessage); /* 签名 */

                String tmpRetStr = sendUnifiedToBank(params, bankFront.getUrl("GW02Qry"));

                if (StringHelper.hasAnyChar(tmpRetStr)) {
                    if (tmpRetStr.indexOf("{") >= 0) {
                        JSONObject respJson = JSONObject.parseObject(tmpRetStr);

                        String respCode = respJson.getString("retcode");
                        if ("SUCCESS".equals(respCode)) {
                            retAts.respCode = "0";
                            retAts.respInfo = respJson.getString("retmsg");
                            String trxStatus = respJson.getString("trxstatus");
                            if (StringHelper.hasAnyChar(trxStatus)) {
                                if ("0000".equals((trxStatus))) {
                                    retAts.refundState = RefundState.REFUND_SUCCESS;
                                } else if ("2008".equals(trxStatus) || "2000".equals(trxStatus)) {
                                    retAts.refundState = RefundState.REFUND_PAYING;
                                } else if ("1001".equals(trxStatus)) {
                                    if (canBeNotExist(p_reqQryRef, retAts, 45)) {
                                        retAts.refundState = RefundState.REFUND_FAIL;
                                    }
                                } else {
                                    String payState = this.getBankConfig().getMapAdvanceValue("recRefundMapping", "key", "payState", trxStatus);
                                    if ("3".equals(payState)) {
                                        retAts.refundState = RefundState.REFUND_FAIL;
                                    } else {
                                        retAts.refundState = RefundState.REFUND_PAYING;
                                    }
                                }
                            } else {
                                retAts.refundState = RefundState.REFUND_PAYING;
                            }

                            retAts.originalCode = trxStatus;
                            String originalInfo = respJson.getString("errmsg");
                            if (StringHelper.isNullOrEmpty(originalInfo)) {
                                originalInfo = "SUCCESS";
                            }
                            retAts.originalInfo = originalInfo;
                            retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", trxStatus);
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = respJson.getString("retmsg");
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpRetStr;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "银联响应为空";
                }

            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_reqQryRef.ownAct + "]商户配置信息!";
            }
        } catch (Exception e) {
            e.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            WriteBankLogLn(e);
        }
        return retAts;
    }

    public RetAtsQryRecRefund queryOrdinaryRecRefund(ReqQryRecRefund p_reqQryRef) throws Exception {
        RetAtsQryRecRefund retAts = new RetAtsQryRecRefund();
        retAts.oriRdSeq = p_reqQryRef.oriRdSeq;
        retAts.refundNo = p_reqQryRef.refundNo;
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQryRef.ownAct, "unifiedorder");
            if (actItem != null) {
                TreeMap<String, String> params = new TreeMap<String, String>();

                params.put("cusid", actItem.merchantId);/* 商户号 */
                params.put("appid", actItem.appId); /* 应用ID*/
                params.put("version", "11");/* 版本号 */
                params.put("reqsn", p_reqQryRef.refundNo); /* 商户订单号 */
                params.put("trxid", "");/* 平台交易流水 */
                params.put("randomstr", get_nonce_str());/* 随机字符串 */
                params.put("sign", SybUtil.sign(params, actItem.saltKey)); /* 签名 */

                String tmpRetStr = sendUnifiedToBank(params, bankFront.getUrl("unifiedOrderQuery"));

                if (StringHelper.hasAnyChar(tmpRetStr)) {
                    if (tmpRetStr.indexOf("{") >= 0) {
                        JSONObject respJson = JSONObject.parseObject(tmpRetStr);

                        String respCode = respJson.getString("retcode");
                        if ("SUCCESS".equals(respCode)) {
                            retAts.respCode = "0";
                            retAts.respInfo = respJson.getString("retmsg");
                            String trxStatus = respJson.getString("trxstatus");
                            if (StringHelper.hasAnyChar(trxStatus)) {
                                if ("0000".equals((trxStatus))) {
                                    retAts.refundState = RefundState.REFUND_SUCCESS;
                                } else if ("2008".equals(trxStatus) || "2000".equals(trxStatus)) {
                                    retAts.refundState = RefundState.REFUND_PAYING;
                                } else if ("1001".equals(trxStatus)) {
                                    if (canBeNotExist(p_reqQryRef, retAts, 45)) {
                                        retAts.refundState = RefundState.REFUND_FAIL;
                                    }
                                } else {
                                    String payState = this.getBankConfig().getMapAdvanceValue("recRefundMapping", "key", "payState", trxStatus);
                                    if ("3".equals(payState)) {
                                        retAts.refundState = RefundState.REFUND_FAIL;
                                    } else {
                                        retAts.refundState = RefundState.REFUND_PAYING;
                                    }
                                }
                            } else {
                                retAts.refundState = RefundState.REFUND_PAYING;
                            }

                            retAts.originalCode = trxStatus;
                            String originalInfo = respJson.getString("errmsg");
                            if (StringHelper.isNullOrEmpty(originalInfo)) {
                                originalInfo = "SUCCESS";
                            }
                            retAts.originalInfo = originalInfo;
                            retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", trxStatus);
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = respJson.getString("retmsg");
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpRetStr;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "银联响应为空";
                }

            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_reqQryRef.ownAct + "]商户配置信息!";
            }
        } catch (Exception e) {
            e.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            WriteBankLogLn(e);
        }
        return retAts;
    }
}
